﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;

using Cards.Util;
using Cards.GUI;
using Cards.Objects;

namespace Cards.Objects
{
    public class CVNPockerPlayer : CPlayer
    {
        protected ArrayList m_coupleCards;      //tat ca cac doi
        protected ArrayList m_pine; //cac doi thong
        protected ArrayList[] m_sortedArray;      //tat ca cac loc
        protected ArrayList[] m_4cards;    //cac tu qui
        protected ArrayList m_singleCards;  //cac quan bai le
        protected ArrayList[] m_3cards;       //3 quan

        public CVNPockerPlayer(String _name, INS_Player _insPlayer): base(_name, _insPlayer)
        {
        }

        public void Win()
        {
            m_insPlayer.SetStateText("Hết bài");

            if (MainFrame.s_multiType == MULTI_PLAYER_TYPE.SINGLE_PLAYER)
            {
                if (m_insPlayer.PLAYERKIND == PLAYER_TYPE.COMPUTER)
                {
                    m_insPlayer.HideGPic();
                }
            }
            else
            {
                if ((this.IP.INSSTAGE[INS_Stage.sSide].PLAYERKIND == PLAYER_TYPE.COMPUTER) ||
                    ((this.IP.INSSTAGE[INS_Stage.sSide].PLAYERKIND == PLAYER_TYPE.HUMAN)
                    && (this.IP.INSSTAGE[INS_Stage.sSide].STT != MainFrame.m_frmMultiGame.GAMEPLAYERID - 1)))
                {
                    m_insPlayer.HideGPic();
                }
            }

            m_winpos = ++INS_VNPockerStage.sWinPos;

            if (MainFrame.s_numOfPlayers == Constants.VNPOCKER_MAX_PLAYERS)
            {
                if (m_winpos == 1)
                {
                    m_winmoney = INS_VNPockerStage.sBetMoney * 2;
                }
                else if (m_winpos == 2)
                {
                    m_winmoney = INS_VNPockerStage.sBetMoney;
                }
                else if (m_winpos == 3)
                {
                    m_winmoney = -INS_VNPockerStage.sBetMoney;
                }
            }
            else
            {
                if (m_winpos == 1)
                {
                    m_winmoney = INS_VNPockerStage.sBetMoney * MainFrame.s_numOfPlayers;
                }
                else if (m_winpos == 2)
                {
                    m_winmoney = -INS_VNPockerStage.sBetMoney;
                }
                else if (m_winpos == 3)
                {
                    m_winmoney = -INS_VNPockerStage.sBetMoney * 2;
                }
            }

            this.m_win = true;
            INS_VNPockerStage.sRemainPlayers--;
            INS_VNPockerStage.sLoseRate = 1;
        }

        public void CreateCardArrays()
        {
            m_4cards = Find4Cards();
            m_pine = FindFines();
            m_coupleCards = FindAllCouple();
            m_3cards = Find3Cards();
            m_sortedArray = FindAllSortedArray();
            m_singleCards = FindAllSingleCards();
        }

        public void DeleteArrayCards()
        {
            if (m_4cards != null)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (m_4cards[i] != null && m_4cards[i].Count > 0)
                    {
                        m_4cards[i].Clear();
                    }
                }
            }
            if (m_pine != null && m_pine.Count > 0)
            {
                m_pine.Clear();
            }
            if (m_coupleCards != null && m_coupleCards.Count > 0)
            {
                m_coupleCards.Clear();
            }
            if (m_3cards != null)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (m_3cards[i] != null && m_3cards[i].Count > 0)
                    {
                        m_3cards[i].Clear();
                    }
                }
            }
            if (m_sortedArray != null)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (m_sortedArray[i] != null && m_sortedArray[i].Count > 0)
                    {
                        m_sortedArray[i].Clear();
                    }
                }
            }
            if (m_singleCards != null && m_singleCards.Count > 0)
            {
                m_singleCards.Clear();
            }
        }

        public ArrayList[] Find3Cards()
        {
            ArrayList[] kq = new ArrayList[4];
            int k = 0;

            for (int i = 12; i > 0; i--)
            {
                for (int j = i - 1; j >= 0; j--)
                {
                    if (!m_insPlayer[i].CARD.PLAY &&
                        (m_insPlayer[i].CARD.CARDVALUE == m_insPlayer[j].CARD.CARDVALUE))
                    {
                        if (kq[k] == null)
                        {
                            kq[k] = new ArrayList();
                            kq[k].Add(m_insPlayer[i]);
                        }
                        kq[k].Add(m_insPlayer[j]);
                        i = j;
                    }
                }

                if (kq[k] != null)
                {
                    if (kq[k].Count == 3)
                    {
                        k++;
                    }
                    else
                    {
                        kq[k].Clear();
                        kq[k] = null;
                    }
                }
            }
            return kq;
        }

        public ArrayList FindAllSingleCards()
        {
            ArrayList kq = new ArrayList();
            for (int i = 12; i >= 0; i--)
            {
                if (!m_insPlayer[i].CARD.PLAY &&
                    ((!In2Cards(m_insPlayer[i].CARD.CARDVALUE) &&
                    !In3Cards(m_insPlayer[i].CARD.CARDVALUE) &&
                    !In4Cards(m_insPlayer[i].CARD.CARDVALUE) &&
                    !InSortedArray(m_insPlayer[i].CARD.CARDTYPE) &&
                    !InCouple(m_insPlayer[i].CARD.CARDTYPE) &&
                    !InPine(m_insPlayer[i].CARD.CARDTYPE))
                    || (InCoupleAndInSortedArray(m_insPlayer[i].CARD.CARDTYPE,
                                             m_insPlayer[i].CARD.CARDVALUE))))
                {
                    kq.Add(m_insPlayer[i]);
                }
            }
            return kq;
        }

        public ArrayList FindAllCouple()
        {
            ArrayList kq = new ArrayList();

            for (int i = 12; i > 0; i--)
            {
                for (int j = i - 1; j >= 0; j--)
                {
                    if (!m_insPlayer[i].CARD.PLAY &&
                        !m_insPlayer[j].CARD.PLAY &&
                        !InPine(m_insPlayer[i].CARD.CARDTYPE) &&
                        !InPine(m_insPlayer[j].CARD.CARDTYPE) &&
                        !In4Cards(m_insPlayer[i].CARD.CARDTYPE) &&
                        !In4Cards(m_insPlayer[j].CARD.CARDTYPE) &&
                        (m_insPlayer[i].CARD.CARDVALUE ==
                            m_insPlayer[j].CARD.CARDVALUE))
                    {
                        SCouple qb;
                        qb.a = m_insPlayer[i];
                        qb.b = m_insPlayer[j];
                        kq.Add(qb);
                        i = j;
                        break;
                    }
                }
            }

            return kq;
        }

        public ArrayList[] Find4Cards()
        {
            ArrayList[] kq = new ArrayList[4];
            int k = 0;

            for (int i = 12; i > 0; i--)
            {
                for (int j = i - 1; j >= 0; j--)
                {
                    if (!m_insPlayer[i].CARD.PLAY &&
                        !m_insPlayer[j].CARD.PLAY &&
                        (m_insPlayer[i].CARD.CARDVALUE
                          == m_insPlayer[j].CARD.CARDVALUE))
                    {
                        if (kq[k] == null)
                        {
                            kq[k] = new ArrayList();
                            kq[k].Add(m_insPlayer[i]);
                        }
                        kq[k].Add(m_insPlayer[j]);
                        i = j;
                    }
                }

                if (kq[k] != null)
                {
                    if (kq[k].Count == 4)
                    {
                        k++;
                    }
                    else
                    {
                        kq[k].Clear();
                        kq[k] = null;
                    }
                }
            }

            return kq;
        }

        public ArrayList FindFines()
        {
            ArrayList kq = new ArrayList();
            Boolean flag = false;

            for (int i = 12; i > 0; i--)
            {
                for (int j = i - 1; j >= 0; j--)
                {
                    if (!m_insPlayer[i].CARD.PLAY &&
                        !m_insPlayer[j].CARD.PLAY
                        && m_insPlayer[i].CARD.CARDVALUE != Constants.GT_HEO
                        && m_insPlayer[j].CARD.CARDVALUE != Constants.GT_HEO
                        && (m_insPlayer[i].CARD.CARDVALUE ==
                            m_insPlayer[j].CARD.CARDVALUE))
                    {
                        if (kq.Count > 0)
                        {
                            if (m_insPlayer[i].CARD.CARDVALUE ==
                                ((SCouple)kq[kq.Count - 1]).a.CARD.CARDVALUE)
                            {
                                break;
                            }

                            if (m_insPlayer[i].CARD.CARDVALUE -
                                ((SCouple)kq[kq.Count - 1]).a.CARD.CARDVALUE != 1)
                            {
                                if (kq.Count < 3)
                                {
                                    kq.Clear();
                                }
                                else
                                {
                                    flag = true;
                                }
                                break;
                            }
                        }

                        SCouple qb;
                        qb.a = m_insPlayer[i];
                        qb.b = m_insPlayer[j];
                        kq.Add(qb);
                        i = j;
                        break;
                    }
                }
                if (flag)
                {
                    break;
                }
            }

            if (kq.Count < 3)
            {
                kq.Clear();
            }

            return kq;
        }

        public ArrayList[] FindAllSortedArray()
        {
            ArrayList[] kq = new ArrayList[4];
            int doi = 0;

            int k = 0;
            //kq[k] = new ArrayList();

            for (int i = 11; i >= 0; i--)
            {
                if (!m_insPlayer[i].CARD.PLAY &&
                    !m_insPlayer[i + 1].CARD.PLAY &&
                    m_insPlayer[i].CARD.CARDVALUE
                    == m_insPlayer[i + 1].CARD.CARDVALUE)
                {
                    doi++;
                    if (kq[k] == null)
                    {
                        kq[k] = new ArrayList();
                        kq[k].Add(m_insPlayer[i]);
                    }
                    continue;
                }

                if (m_insPlayer[i].CARD.CARDVALUE == Constants.GT_HEO)
                {
                    break;
                }

                if (!m_insPlayer[i].CARD.PLAY &&
                    !m_insPlayer[i + 1].CARD.PLAY &&
                    !InPine(m_insPlayer[i].CARD.CARDTYPE)
                    && !InPine(m_insPlayer[i + 1].CARD.CARDTYPE) &&
                    !In4Cards(m_insPlayer[i].CARD.CARDVALUE)
                    && !In4Cards(m_insPlayer[i + 1].CARD.CARDVALUE) &&
                    (m_insPlayer[i].CARD.CARDVALUE
                        - m_insPlayer[i + 1].CARD.CARDVALUE == 1))
                {
                    if (kq[k] == null)
                    {
                        kq[k] = new ArrayList();
                        kq[k].Add(m_insPlayer[i + 1]);
                    }
                    kq[k].Add(m_insPlayer[i]);
                }
                else
                {
                    if (kq[k] != null)
                    {
                        if (kq[k].Count >= 3 && kq[k].Count - doi > 2
                            || (kq[k].Count == 3 && doi == 1))
                        {
                            k++;
                        }
                        else
                        {
                            kq[k].Clear();
                            kq[k] = null;
                        }
                        doi = 0;
                    }
                    else
                    {
                        doi = 0;
                    }
                }
            }

            for (int i = 0; i < 4; i++)
            {
                if (kq[i] != null && kq[i].Count < 3)
                {
                    kq[i].Clear();
                    kq[i] = null;
                }
            }

            return kq;
        }

        public Boolean CheckWin6Couple()
        {
            if (m_coupleCards != null && m_coupleCards.Count == 6)
            {
                return true;
            }
            return false;
        }

        public Boolean Check4Fines()
        {
            DeleteArrayCards();
            CreateCardArrays();
            if (m_pine != null && m_pine.Count == 4)
            {
                return true;
            }
            return false;
        }

        public Boolean CheckWin5Fines()
        {
            if (m_pine != null && m_pine.Count == 5)
            {
                return true;
            }
            return false;
        }

        public Boolean CheckWin6Fines()
        {
            if (m_pine != null && m_pine.Count == 6)
            {
                return true;
            }
            return false;
        }

        public Boolean CheckWin4Pigs()
        {
            for (int i = 0; i < 4; i++)
            {
                if (m_4cards[i] != null &&
                    ((INS_Card)m_4cards[i][0]).CARD.CARDVALUE == Constants.GT_HEO)
                {
                    return true;
                }
            }
            return false;
        }

        public Boolean CheckWinSortedArray()
        {
            for (int i = 0; i < 4; i++)
            {
                if (m_sortedArray[i] != null
                    && m_sortedArray[i].Count == 12
                    && m_insPlayer[0].CARD.CARDVALUE == Constants.GT_HEO)
                {
                    return true;
                }
            }
            return false;
        }


        public Boolean In2Cards(int _value)
        {
            int count = 0;
            for (int i = 12; i >= 0; i--)
            {
                if (!m_insPlayer[i].CARD.PLAY &&
                    m_insPlayer[i].CARD.CARDVALUE == _value)
                {
                    count++;
                }
            }
            if (count == 2)
            {
                return true;
            }
            return false;
        }
        public Boolean In3Cards(int _value)
        {
            int count = 0;
            for (int i = 12; i >= 0; i--)
            {
                if (!m_insPlayer[i].CARD.PLAY &&
                    m_insPlayer[i].CARD.CARDVALUE == _value)
                {
                    count++;
                }
            }
            if (count == 3)
            {
                return true;
            }
            return false;
        }
        public Boolean In4Cards(int _value)
        {
            int count = 0;
            for (int i = 12; i >= 0; i--)
            {
                if (!m_insPlayer[i].CARD.PLAY &&
                    m_insPlayer[i].CARD.CARDVALUE == _value)
                {
                    count++;
                }
            }
            if (count == 4)
            {
                return true;
            }
            return false;
        }
        public Boolean InSortedArray(int _value)
        {
            for (int i = 0; i < 4; i++)
            {
                if (m_sortedArray[i] != null)
                {
                    for (int j = 0; j < m_sortedArray[i].Count; j++)
                    {
                        if (((INS_Card)m_sortedArray[i][j]).CARD.CARDTYPE == _value)
                        {
                            return true;
                        }
                    }
                }
            }
            return false;
        }

        public Boolean InPine(int _value)
        {
            if (m_pine != null)
            {
                for (int i = 0; i < m_pine.Count; i++)
                {
                    if (((INS_Card)((SCouple)m_pine[i]).a).CARD.CARDTYPE == _value ||
                        ((INS_Card)((SCouple)m_pine[i]).b).CARD.CARDTYPE == _value)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public Boolean InCouple(int _value)
        {
            if (m_coupleCards != null)
            {
                for (int i = 0; i < m_coupleCards.Count; i++)
                {
                    if (((INS_Card)((SCouple)m_coupleCards[i]).a).CARD.CARDTYPE == _value ||
                        ((INS_Card)((SCouple)m_coupleCards[i]).b).CARD.CARDTYPE == _value)
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        public Boolean InCoupleAndInSortedArray(int _value, int _loai)
        {
            if (InCouple(_value) && !InSortedArray(_value))
            {
                for (int i = 0; i < 4; i++)
                {
                    if (m_sortedArray[i] != null)
                    {
                        for (int j = 0; j < m_sortedArray[i].Count; j++)
                        {
                            if (((INS_Card)m_sortedArray[i][j]).CARD.CARDVALUE == _loai &&
                                ((INS_Card)m_sortedArray[i][j]).CARD.CARDTYPE != _value)
                            {
                                return true;
                            }
                        }
                    }
                }
            }
            return false;
        }

        public long ExtraBillLose()
        {
            long result = 0;

            for (int i = 0; i < 13; i++)
            {
                if (m_insPlayer[i].CARD.CARDVALUE == Constants.GT_HEO && !m_insPlayer[i].CARD.PLAY)
                {
                    result += (m_insPlayer[i].CARD.CARDTYPE - 48) * INS_VNPockerStage.sBetMoney;
                }
            }

            if (m_4cards != null)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (m_4cards[i] != null && m_4cards[i].Count > 0)
                    {
                        result += INS_VNPockerStage.sBetMoney * 4;
                    }
                }
            }

            if (m_pine != null && m_pine.Count > 0)
            {
                if (m_pine.Count == 3)
                {
                    result += INS_VNPockerStage.sBetMoney * 2;
                }
                else if (m_pine.Count == 4)
                {
                    result += INS_VNPockerStage.sBetMoney * 4;
                }
            }

            return result;
        }
    }
}
